package com.fastdfs.util;

import com.alibaba.fastjson.JSON;
import org.junit.Test;
import redis.clients.jedis.*;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;



//  想要 修改在Redis中的值就是覆盖   也就是在设置一遍

public class RedisUtis {



    private static   int  time=86400;  //1天过期时间

    private static boolean timepd=false;   //是否开启 key  永不过期    true开启     如果开启后上面的 time将失效  一般不要开启
 

    // ------------字符串操作----------------------------------------

    //单个获取  通过key 获取value
    public static String getStringRedis(String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度

        String s = null;
        try {
            Response<String> stringResponse = pipe.get(key);
            pipe.close();
            s = stringResponse.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            jedis.close();
        }

        return s  ;
    }
    //批量获取   自动过滤  不存在的key
    public static List<String> getStringRedis(String... key){
        List<Response<String>> list=new ArrayList<>();
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        for (String s : key) {
            Response<String> stringResponse = pipe.get(s);
            list.add(stringResponse);
        }
        pipe.close();
        jedis.close();

        List<String> list1=new ArrayList<String>();
        list.stream().filter(stringResponse -> {return stringResponse.get()!=null&& !stringResponse.get().equals("");})
                .forEach(s->{
                    list1.add(s.get());
                });

        return  list1 ;
    }


    //删除指定String (泛型)
    public  static boolean delStringRedis(String... key){
        return delKeyRedis(key) ;
    }



    //单个设置  缓存字符串    (list  map   数组  实体类 ) 会自动 转换为  json格式 字符串如果不是json格式  那么就原样 转为 字符串     (8大基本数据类型 自动转换为字符串格式)
    public static boolean setStringRedis(String key, Object obj) {

        if(!NullUtils.notEmpty( key)&&!NullUtils.notEmpty( obj)){
            return false ;
        }
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Boolean exists = jedis.exists(key);
        if (exists){
            pipe.del(key);
        }
        try {
            if (obj instanceof String){
                pipe.set(key, (String)obj);
            }else{
                pipe.set(key, JSON.toJSONString(obj));
            }

            pipe.close();

            if(timepd){ //判断是否设置永久不过期
                Response<Long> ttl1 = pipe.ttl(key); //获取过期时间
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(key);
                }
            }else{  //设置指定的过期时间
                pipe.close();
                jedis.expire(key,time);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("设置json缓存失败");
            return false ;
        }finally {

            jedis.close();
        }
        return true ;
    }
    
    //批量设置  缓存字符串     (list  map   数组  实体类 ) 会自动 转换为  json格式 字符串如果不是json格式  那么就原样 转为 字符串     (8大基本数据类型 自动转换为字符串格式)
    public static  boolean setStringRedis(Map<String,Object> map){
        if(!NullUtils.notEmpty(map)){
            return false;
        }
        Jedis jedis = JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try {
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            for (Map.Entry<String, Object> entry : entries) {
                if (jedis.exists(entry.getKey())) {
                    pipe.del(entry.getKey());
                }
                if (entry.getValue() instanceof String){
                    pipe.set(entry.getKey(),(String) entry.getValue());
                }else{
                    pipe.set(entry.getKey(),JSON.toJSONString(entry.getValue()));
                }

                if(timepd){
                    Response<Long> ttl1 = pipe.ttl(entry.getKey());
                    pipe.close();
                    if(ttl1.get()!=-1){
                        jedis.persist(entry.getKey());
                    }
                }else{
                    pipe.close();
                    jedis.expire(entry.getKey(),time);
                }



            }

        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {

            jedis.close();
        }

        return  true;

    }



    // --------------------------------map -----------------------------------
    //  双列存储    无序也就是查询的时候和插入的顺序可能不一致      键唯一   值不唯一

    //设置  Map<String,String> 的数据  到 Redis 里
    public static boolean setMapRedis(String key,Map<String,String> map){
        if(!NullUtils.notEmpty(key)&&!NullUtils.notEmpty(map)){
            return false ;
        }
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Boolean exists = jedis.exists(key);
        if (exists) {
            pipe.del(key);
        }
        try {
           jedis.hmset(key,map);
            if(timepd){
                Response<Long> ttl1 = pipe.ttl(key);
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(key);
                }
            }else{
                pipe.close();
                jedis.expire(key,time);
            }


        } catch (Exception e) {
            e.printStackTrace();
            return false ;
        } finally {

            jedis.close();
        }
        return  true;
    }


    //添加指定map的key值
    public static boolean setMapRedis(String mapkey,String key ,String value){
        if(!NullUtils.notEmpty(mapkey)&&!NullUtils.notEmpty( key)&&!NullUtils.notEmpty( value)){
            return false ;
        }
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Boolean exists = jedis.exists(key);
        if (exists) {
            pipe.del(key);
        }
        try {
             jedis.hset(mapkey,key,value);
            if(timepd){
                Response<Long> ttl1 = pipe.ttl(mapkey);
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(mapkey);
                }
            }else{
                pipe.close();
                jedis.expire(mapkey,time);
            }


        } catch (Exception e) {
            e.printStackTrace();
            return false ;
        } finally {

            jedis.close();
        }
        return  true;
    }


    // 获取 指定 Map 内的key 值
    public static String getMapRedis(String mapkey ,String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        String hget = null;
        try {
            Response<String> hget1 = pipe.hget(mapkey, key);
            pipe.close();
            hget = hget1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return  hget;
    }
    //获取自动Map 内多个key的值
    public static  List<String> getMapRedis(String mapkey ,String... key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        List<String> hmget = null;
        try {
            Response<List<String>> hmget1 = pipe.hmget(mapkey, key);
            pipe.close();
            hmget = hmget1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return hmget;
    }

    // 获取全部指定Map 全部内容
    public static   Map<String, String> getMapRedis(String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Map<String, String> map= null;
        try {
            Response<Map<String, String>> mapResponse = pipe.hgetAll(key);
            pipe.close();
            map = mapResponse.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return map;

    }
    // 删除指定map中的 key     key是泛型  可以一次性删除多个key    删除成功返回 true
    public static  boolean delMapRedis(String mapkey ,String... key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try {
            pipe.hdel(mapkey,key);
        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {
            pipe.close();
            jedis.close();
        }
        return true;

    }
    // 删除指定map中的 全部key    (泛型)  可以删除多个map   注意是map的key(名称)  而不是map里面的key
    public static  boolean delMapRedis(String... key){
        return delKeyRedis(key);

    }



    // -------------------------------sortedset    有序集合  值唯一
    // 单列存储     类似等同于 set    但是数据是有序的

    /**
     *
     *     设置 Sortedset集合 内容
     *
     *      向有序list 里添加值   插入1个或者多个    插入成功返回true  失败false
     *      第二个参数是分数(可选 默认0) 意思是指定顺序正是通过此数值来为集合中的成员进行从小到大的排序   和分类
     *      如果数值相同那么就按照插入的顺序   如果懒得设置都为0就行了
     *     注意 值是唯一的   相同的值会被覆盖的
     *
     *
     * @param key    集合名称
     * @param score  分数  (可选)
     * @param value  值   (泛型)
     */
    public static  boolean setSortedsetRedis(String key,double score,String... value){
        if(!NullUtils.notEmpty( key)&&!NullUtils.notEmpty( score)&&!NullUtils.notEmpty( value)){
            return false ;
        }
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Boolean exists = jedis.exists(key);
        if (exists) {
            pipe.del(key);
        }
        try {
            for (String s : value) {
                pipe.zadd( key,score,s);
            }
            if(timepd){
                Response<Long> ttl1 = pipe.ttl(key);
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(key);
                }
            }else{
                pipe.close();
                jedis.expire(key,time);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {
            jedis.close();
        }
        return true;
    }
    //默认为0分数
    public static boolean setSortedsetRedis(String key,String... value){
       return setSortedsetRedis(key,0,value);
    }



    /**
     *
     *  获取 Sortedset 集合中的内容
     *
     * @param key  集合名称
     * @param min   分数起始位置
     * @param max  分数结束位置
     * @return   Set<String>
     */
    //返回指定 区间 分数  全部值
    public static  Set<String> getSortedsetRedis(String key,double min, double max){

        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理
        Set<String> mysort2 = null;
        try {
            Response<Set<String>> setResponse = pipe.zrangeByScore(key, min, max);
            pipe.close();
            mysort2 = setResponse.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return mysort2;
    }
    //返回指定分数 内全部值
    public static  Set<String> getSortedsetRedis(String key,double min){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理
        Set<String> mysort2 = null;
        try {
            Response<Set<String>> setResponse = pipe.zrangeByScore(key, min, min);
            pipe.close();
            mysort2 = setResponse.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return mysort2;
    }



    /**
     * 返回多个 指定分数 内全部值
     * @param key  集合名称
     * @param min  (泛型)   要求参数>=3  不存在也没关系       否则就是调用getSortedsetRedis(String key,double min, double max) 这个方法了
     * @return Set<String>
     */
    public static  Set<String> getSortedsetRedis(String key,double... min){
        Set<String> set=new LinkedHashSet<>();
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理
        List<  Response<Set<String>>> list=new ArrayList<>();
        try {
            for (int i = 0; i < min.length; i++) {

                Response<Set<String>> setResponse = pipe.zrangeByScore(key, min[i], min[i]);
                list.add(setResponse);
                set.addAll(setResponse.get());
            }
            pipe.close();
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            list.forEach(dao->{
                set.addAll(dao.get());
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return set;
    }




    //默认返回 0分数 内全部值  如果0分没有值  那么查询全部的值
    public static  Set<String> getSortedsetRedis(String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理
        Set<String> mysort2 = null;
        try {
            Response<Set<String>> setResponse = pipe.zrangeByScore(key, 0, 0);
            pipe.close();
            mysort2 = setResponse.get();
            if(!NullUtils.notEmpty(mysort2)){
                mysort2= jedis.zrange( key,0,-1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return mysort2;

    }

    /**
     *获取 Sortedset 指定分数区间数据的 个数
     * @param key  集合名称
     * @param min   分数起始位置
     * @param max  分数结束位置
     * @return Long
     */
    public static  Long getSortedsetRedisCount(String key,double min, double max){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理
        Long zcount = null;
        try {
            Response<Long> zcount1 = pipe.zcount(key, min, max);
            pipe.close();
            zcount = zcount1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return zcount;
    }



    /**
     *
     *  删除 Sortedset 集合 分数中的内容
     *
     * @param key  集合名称
     * @param min   分数起始位置
     * @param max  分数结束位置
     * @return   Set<String>
     */
    //删除 区间分数内的值
    public static boolean delSortedsetRedis(String key,double min, double max){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理
        Long mysort3 = null;
        try {
            Response<Long> longResponse = pipe.zremrangeByScore(key, min, max);
            pipe.close();
            mysort3 = longResponse.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        if(mysort3 >=1){
            return true;
        }
        return  false;
    }
    //删除 指定分数内的值
    public static boolean delSortedsetRedis(String key,double min){
        return  delSortedsetRedis(key,min,min);
    }
    //删除多个指定分数的值     (泛型 参数)>=3   否则就是区间删除
    public static boolean delSortedsetRedis(String key,double... min){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理

        try {
            for (double v : min) {
             pipe.zremrangeByScore(key, v, v);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        }finally {
            pipe.close();
            jedis.close();
        }

        return  true;
    }
    //删除指定集合全部数据  (泛型)  可以删除多个
    public static  boolean delSortedsetRedis(String... key){
        return delKeyRedis(key);
    }
    //删除 指定集合内 指定的 value  (泛型)   可以同时删除多个
    public static boolean delSortedsetRedis(String key,String... value){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        long de= 0;
        try {
            Response<Long> zrem = pipe.zrem(key, value);
            pipe.close();
            de = zrem.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        if(de >=1){
            return true;
        }
        return  false;

    }


    // --------------------------------List集合-----------------


    //单例集合 有序    数据可重复

    /**
     * 结尾位置 插入数据  单个 或者 多个
     * @param key  List的名称
     * @param value  要插入的值    (泛型)
     * @return   插入成功 true
     */
    public static boolean setListRedisEnd(String key,String... value){
        if(!NullUtils.notEmpty( key)&&!NullUtils.notEmpty( value)){
            return false ;
        }

        Jedis jedis = JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try {
            Boolean exists = jedis.exists(key);
            if (exists) {
                pipe.del(key);
            }
            pipe.rpush(key, value);
            if(timepd){
                Response<Long> ttl1 = pipe.ttl(key);
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(key);
                }
            }else{
                pipe.close();
                jedis.expire(key,time);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {

            jedis.close();
        }
        return  true;
    }
    /**
     * 开头位置 插入数据  单个 或者 多个
     * @param key  List的名称
     * @param value  要插入的值    (泛型)
     * @return   插入成功 true
     */
    public  static boolean setListRedisStart(String key,String... value){
        if(!NullUtils.notEmpty( key)&&!NullUtils.notEmpty( value)){
            return false ;
        }
        Jedis jedis = JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try  {
            Boolean exists = jedis.exists(key);
            if (exists) {
                pipe.del(key);
            }
            pipe.lpush(key, value);
            if(timepd){
                Response<Long> ttl1 = pipe.ttl(key);
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(key);
                }
            }else{
                pipe.close();
                jedis.expire(key,time);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {

            jedis.close();
        }
        return true;
    }


    /**
     * 删除 list 的指定值
     * @param key  List名称
     * @param count  要删除的个数     比如{1,2,3,1,1,1}  此List中有4个相同的1    使用 count  来控制删除几个
     *               正数从左边开始   负数从右边开始
     * @param value  删除成功 true
     */
    public static boolean delListRedis(String key, long count, String value){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Long lrem = null;
        try {
            Response<Long> lrem1 = pipe.lrem(key, count, value);
            pipe.close();
            lrem = lrem1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        if(lrem>=1){
            return  true;
        }
        return  false;
    }
    // 删除List里 指定的元素和这个元素全部重复数据    0删除指定元素的全部重复
    public static boolean delListRedis(String key,  String value){

        return  delListRedis(key,0,value);
    }
    // 删除List里 多个指定的元素  和这个元素全部重复数据
    public static boolean delListRedis(String key,  String... value){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try {
            for (String s : value) {
                pipe.lrem(key, 0, s);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {
            pipe.close();
            jedis.close();
        }
        return  true;
    }



    /**
     *     对一个列表进行修剪(trim)，就是说，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除。
     *     下标 0 表示列表的第一个元素，以 1 表示列表的第二个元素，以此类推。 你也可以使用负数下标，
     *     以 -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推。
     * @param key  List名称
     * @param start   开启位置
     * @param end    结束位置
     * @return   删除成功 true
     */

    public static boolean delListRedis(String key,long start, long end){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        String day12 = null;
        try {
            Response<String> ltrim = pipe.ltrim(key, start, end);
            pipe.close();
            day12 = ltrim.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        if(day12.equals("ok")){
            return  true;
        }
        return  false;
    }

    //删除 指定List的全部的值  (泛型)  可以删除多个list
    public static boolean delListRedis(String... key){
        return  delKeyRedis(key);
    }

    /**
     *
     *       获取List指定区间的数据
     *       其中 0 表示列表的第一个元素， 1 表示列表的第二个元素，以此类推
     *       -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推。
     *
     * @param key List名称
     * @param start  起始位置
     * @param end   结束位置
     * @return   List<String>
     */

    public static List<String> getListRedis(String key,long start, long end){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        List<String> list= null;
        try {
            Response<List<String>> lrange = pipe.lrange(key, start, end);
            pipe.close();
            list = lrange.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return   list;
    }

    /**
     * 获取指定下标的元素
     * @param key  List名称
     * @param index  元素下标位置
     * @return  String
     */
    public static String getListRedis(String key,long index){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        String day1 = null;
        try {
            Response<String> lindex = pipe.lindex(key, index);
            pipe.close();
            day1 = lindex.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }
        return day1;
    }
    /**
     * 获取多个指定下标的元素
     * @param key  List名称
     * @param index  元素下标位置
     * @return  String
     */
    public static  List<String> getListRedis(String key,long... index){

    List<Response<String>> list=new ArrayList<>();
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try {
            for (long l : index) {
                Response<String> lindex1 = pipe.lindex(key, l);
                list.add(lindex1);
            }
            pipe.close();
            jedis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<String> list1=new ArrayList<String>();
        list.stream().filter(stringResponse -> {return stringResponse.get()!=null&& !stringResponse.get().equals("");})
                .forEach(s->{
                    list1.add(s.get());
                });

        return list1;
    }


    // 获取指定List 全部数据
    public static List<String> getListRedis(String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        List<String> list= null;
        try {
            Response<List<String>> lrange = pipe.lrange(key, 0, -1);
            pipe.close();
            list = lrange.get();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {

            jedis.close();
        }

        return   list;
    }




    // --------------------------------Set集合-----------------
    //单列存储     注意 是无序的  但是值唯一

    /**
     * 设置 Set集合的元素
     * @param key Set名称
     * @param value  要设置的值 (泛型)
     * @return 设置成功 true
     */

    public static boolean setSetRedis(String key,String...value){
        if(!NullUtils.notEmpty( key)&&!NullUtils.notEmpty( value)){
            return false ;
        }
        Jedis jedis = JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        try {

            Boolean exists = jedis.exists(key);
            if (exists) {
                pipe.del(key);
            }
            pipe.sadd(key, value);
            if(timepd){
                Response<Long> ttl1 = pipe.ttl(key);
                pipe.close();
                if(ttl1.get()!=-1){
                    jedis.persist(key);
                }
            }else{
                pipe.close();
                jedis.expire(key,time);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  false;
        } finally {

            jedis.close();
        }
        return  true;
    }



    /**
     * 查询 Set集合中是否包含 指定元素
     * @param key Set名称
     * @param value  查询是否包含的值
     * @return   如果包含 true
     */
    public static Boolean eqSetRedis(String key,String value){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Boolean hexists = null;
        try {
            Response<Boolean> sismember = pipe.sismember(key, value);
            pipe.close();
            hexists = sismember.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return  hexists;
    }

    /**
     * 查询指定Set里所有值
     * @param key  Set名称
     * @return   Set<String>
     */

    public  static  Set<String> getSetRedis(String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Set<String> ser1 = null;
        try {
            Response<Set<String>> smembers = pipe.smembers(key);
            pipe.close();
            ser1 = smembers.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return ser1;
    }

    /**
     * 随机从指定Set 选取一个值
     * @param key  Set名称
     * @return String
     */
    public  static  String  getSetRedisRandom (String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        String ser2 = null;
        try {
            Response<String> srandmember = pipe.srandmember(key);
            pipe.close();
            ser2 = srandmember.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return ser2;
    }
    /**
     * 随机从指定Set 选取多个值
     * @param key  Set名称
     * @param count  随机的个数
     * @return   List<String>
     */
    public  static  List<String> getSetRedisRandom (String key,int count){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        List<String> srandmember = null;
        try {
            Response<List<String>> srandmember1 = pipe.srandmember(key, count);
            pipe.close();
            srandmember = srandmember1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return srandmember;
    }

    /**
     * 删除指定Set里的 单个或者多个value元素
     * @param key  Set名称
     * @param value 要删除的元素  (泛型)
     * @return  删除成功 true
     */
    public static boolean delSetRedis(String key,String... value){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Long srem = null;
        try {
            Response<Long> srem1 = pipe.srem(key, value);
            srem = srem1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            pipe.close();
            jedis.close();
        }
        if(srem>=1){
            return  true;
        }
        return false;
    }

    /**
     * 从Reids中 删除Set  (泛型)  (可以删除多个Set)
     * @param key Set名称
     * @return 删除成功true
     */
    public static boolean delSetRedis(String... key){
        return delKeyRedis(key);
    }


// --------------------------- 其他 方法    通用



    //删除指定的key   删除1个或者多个   可以用于 所有类型的key  比如 map String List set  这些存储结构
    public static  boolean delKeyRedis(String... key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Long de= null;
        try {
            Response<Long> del = pipe.del(key);
            pipe.close();
            de = del.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        if (de>=1){
            return  true;
        }
        return  false;
    }


    //获取指定key 过期时间 (时间戳)   如果key是永久的，返回-1      如果是-2 就是此key  以过期
    public static Long gettimeReids(String key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Long map1 = null;
        try {
            Response<Long> pttl = pipe.pttl(key);
            pipe.close();
            map1 = pttl.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }

        return map1;
    }

    //判断Redis中是否存在指定的key
    public static boolean eqKeyRedis(String... key){
        Jedis jedis= JedisPool.Jedis();
        Pipeline pipe = jedis.pipelined();  //管道 批量处理 加快处理速度
        Long exists = null;
        try {
            Response<Long> exists1 = pipe.exists(key);
            pipe.close();
            exists = exists1.get();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            jedis.close();
        }
        if (exists>=1){
            return  true;
        }else {
            return false;
        }
    }



   //Reids 缓存池  (连接池)

 private  static class JedisPool {
        private static redis.clients.jedis.JedisPool jedisPool=null;
        static {
            init();
        }


        private static   void init(){
            InputStream inputStream= RedisUtis.class.getClassLoader().getResourceAsStream("jedis.properties");
            Properties properties=new Properties();
            try {
                properties.load(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                JedisPoolConfig config=new JedisPoolConfig();
                //最大空闲连接数, 默认8个
                config.setMaxIdle(10);
                //最大连接数, 默认8个
                config.setMaxTotal(80);
                //最小空闲连接数, 默认0
                config.setMinIdle(2);

                //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
                config.setMaxWaitMillis(-1);

                //每timeBetweenEvictionRunsMillis毫秒秒检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止
                config.setTimeBetweenEvictionRunsMillis(30000);
                // 连接池中连接可空闲的时间,毫秒 默认1800000毫秒(30分钟) 到时间就驱逐空闲的连接
                config.setMinEvictableIdleTimeMillis(1800000);
                config.setTestOnBorrow(true);
                config.setTestOnReturn(true);
                config.setTestWhileIdle(true);
                config.setNumTestsPerEvictionRun(-1);
                config.setLifo(true);


                //  statc是共享的   连接不一样是 无法返回到连接池  所以防止多次new   (多线程)

                jedisPool=new redis.clients.jedis.JedisPool(config,properties.getProperty("host"),Integer.parseInt(properties.getProperty("port")));
            } catch (NumberFormatException e) {
                if (jedisPool != null) {
                    jedisPool.close();
                }
            }
        }




        private static redis.clients.jedis.JedisPool getPool(){

            if(jedisPool==null){
                synchronized (RedisUtis.class){
                    init();
                }
            }
            return jedisPool;
        }

        //获取 连接
        public  static Jedis Jedis(){
            redis.clients.jedis.JedisPool pool= getPool();
            return  pool.getResource();
        }


    }













    // 查询过期时间
    //当 key 不存在时，返回 -2 。 当 key 存在但没有设置剩余生存时间时，返回 -1 。 否则，以秒为单位，返回 key 的剩余生存时间。
    @Test
    public   void   getKeytime(){
        Jedis jedis= JedisPool.Jedis();
        Long ttl = jedis.ttl("albumAll");
        System.out.println(ttl);
        jedis.close();

    }


    //查询Redis 中全部的keu  (一般用于测试)
    @Test
    public   void   getKeyRedisAll(){
        Jedis jedis= JedisPool.Jedis();
        Set<String> keys = jedis.keys("*");
        System.out.println(keys);
        jedis.close();

    }

    //查询Redis 中全部的keu 的个数  (一般用于测试)
    @Test
    public   void   getKeyRedisSize(){
        Jedis jedis= JedisPool.Jedis();
        Long aLong = jedis.dbSize();
        System.out.println(aLong);
        jedis.close();
    }
    
    


    // 清空所有key   (一般用于测试)
    @Test
    public void delKeyAll(){
        Jedis jedis= JedisPool.Jedis();
        String s = jedis.flushAll();
        System.out.println(s);
        jedis.close();
    }


    //删除指定key
    
    @Test
    public void delsr(){
        boolean b = RedisUtis.delStringRedis("albumAll");
        System.out.println(b);
    }

    // 检测 Redis 使用情况
    @Test
    public void getRedisMemory(){
        Jedis jedis= JedisPool.Jedis();
        String str1="Memory";  //内存使用情况
        String str2="clients";  //已连接客户端信息
        String str3="server";  //Redis 服务器信息
        String info = jedis.info(str1);
        System.out.println(info);
        jedis.close();
    }







}
